﻿using Sustainalytics.Entities;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text.RegularExpressions;
using Ent = Sustainalytics.Entities;

namespace Sustainalytics.News.Service
{
    public class NewsBaseDto
    {
        public Guid Id { get; set; }

        [Required]
        [MaxLength(100)]
        public string Title { get; set; }
    }

    public class NewsDto: NewsBaseDto
    {
        public string TitleLowercase { get; set; }

        [Required]
        public string Body { get; set; }

        public Guid AddedByUserId { get; set; }

        public string AddedByUserName { get; set; }

        [Required]
        public NewsAvailability AvailableFor { get; set; }

        [Required]
        public NewsStatus Status { get; set; }

        public NewsCategory? Category { get; set; }

        [Required]
        [DataType(DataType.Date)]
        public DateTime DateCreated { get; set; }

        [Required]
        [DataType(DataType.Date)]
        public DateTime? UnpublishedDate { get; set; }

        public List<NewsTagDto> Tags { get; set; }

        [Required]
        public NewsRegion Region { get; set; }


        /// <summary>
        /// Ctor.
        /// </summary>
        public NewsDto()
        {
            this.Tags = new List<NewsTagDto>();
        }

        public NewsDto LoadFrom(Ent.News data, bool truncateBody = false)
        {
            this.Id = data.Id;
            this.Title = data.Title;
            this.TitleLowercase = data.TitleLowercase;
            this.Body = truncateBody ? GetBodyForNews(data.Body) : data.Body;
            this.AddedByUserId = data.AddedByUserId;
            this.AddedByUserName = data.AddedByUserName;
            this.AvailableFor = data.AvailableFor;
            this.Status = data.Status;
            this.Category = data.Category;
            this.DateCreated = data.DateCreated;
            this.UnpublishedDate = data.UnpublishedDate;

            this.Tags.Clear();
            this.Tags.AddRange(data.Tags.Select(t => new NewsTagDto().LoadFrom(t)).ToList());

            this.Region = data.Region;

            return this;
        }

        public string GetBodyForNews(string body)
        {
            Match m = Regex.Match(body, "^.*?<p>(.*?)</p>", RegexOptions.Compiled | RegexOptions.IgnoreCase);
            if (m.ToString().Contains("<br/>") || m.ToString().Contains("\n"))
            {
                Match m2 = Regex.Match(m.ToString(), @"(.+?(?:<br\s*\/?>|\n)+)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
                return m2.ToString();
            }
            else
                return m.ToString();
        }
        public NewsBaseDto LoadLess(Ent.News data)
        {
            this.Id = data.Id;
            this.Title = data.Title;

            return this;
        }

        public void SaveToNew(Ent.News data)
        {
            data.Id = this.Id;
            data.Title = this.Title;
            data.TitleLowercase = this.Title == null ? null : this.Title.ToLowerInvariant();
            data.Body = this.Body;
            data.AddedByUserId = this.AddedByUserId;
            data.AddedByUserName = this.AddedByUserName;
            data.AvailableFor = this.AvailableFor;
            data.Status = this.Status;
            data.Category = this.Category;
            data.DateCreated = this.DateCreated;
            data.UnpublishedDate = this.UnpublishedDate;

            data.Tags.Clear();
            data.Tags.AddRange(this.Tags.Select(t =>
                {
                    NewsTag tag = new NewsTag();
                    t.SaveTo(tag);
                    return tag;
                }).ToList());

            data.Region = this.Region;
        }

        public void SaveToExisting(Ent.News data)
        {
            data.Id = this.Id;
            data.Title = this.Title;
            data.TitleLowercase = this.Title == null ? null : this.Title.ToLowerInvariant();
            data.Body = this.Body;
            data.AddedByUserId = this.AddedByUserId;
            data.AddedByUserName = this.AddedByUserName;
            data.AvailableFor = this.AvailableFor;
            data.Status = this.Status;
            data.Category = this.Category;
            data.DateCreated = this.DateCreated;
            data.UnpublishedDate = this.UnpublishedDate;

            data.Tags.Clear();
            data.Tags.AddRange(this.Tags.Select(t =>
            {
                NewsTag tag = new NewsTag();
                t.SaveTo(tag);
                return tag;
            }).ToList());

            data.Region = this.Region;
        }
    }
}
